﻿using System;
using System.Linq;
using DataModels.Common;
using DataModels.Enumerations;
using DataModels.Models;
using GenericTools.Models;
using GenericTools.ReportProcessing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DataModels.Models.Context;

namespace GenericTools.Tests.ReportProcessing
{
    [TestClass]
    public class ReportProcessorTest
    {
        [ClassInitialize]
        public static void MyClassInitialize(TestContext testContext)
        {
            AppConfiguration.AccessMethod = DataModels.Enumerations.DataAccessMethod.DIRECT_ACCESS;
            AppConfiguration.DBConnectionString = @"Data Source=(local)\SQLEXPRESS;Initial Catalog=IQSMS_TestDB.Development;Integrated Security=True";
        }

        [TestMethod]
        public void ANC_Report_Is_Valid()
        {
            string reportingText = "ANC1.04010100,1,2014,1,2,3,4,5,6,7,8,9,10,11,12,13,14";
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);

            Assert.AreEqual("04010100", target.FacilityCode, target.ErrorText);
            Assert.AreEqual(1, target.Period, target.ErrorText);
            Assert.AreEqual(2014, target.Year, target.ErrorText);

            var data = target.ReportData;
            Assert.AreEqual(14, data.Count, target.ErrorText);
            Assert.AreEqual(1, data[0]);
            Assert.AreEqual(2, data[1]);
            Assert.AreEqual(3, data[2]);
            Assert.AreEqual(4, data[3]);
            Assert.AreEqual(5, data[4]);
            Assert.AreEqual(6, data[5]);
            Assert.AreEqual(7, data[6]);
            Assert.AreEqual(8, data[7]);
            Assert.AreEqual(9, data[8]);
            Assert.AreEqual(10, data[9]);
            Assert.AreEqual(11, data[10]);
            Assert.AreEqual(12, data[11]);
            Assert.AreEqual(13, data[12]);
            Assert.AreEqual(14, data[13]);
        }

        [TestMethod]
        public void Report_Processor_Is_Saving_Classical_ANC_Report()
        {
            string facilityCode = "04010100";
            int month = 1;
            int year = 2014;
            string reportKeyword = "ANC1";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},19,0,19,20,1,20,7,0,7,7,0,0,7,1",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            bool bActual = target.Submit();
            Assert.IsTrue(bActual, "Report is not saved");

            using (var db = new IQSMS_TestDBContext())
            {
                var receivedSMS = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == reportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(receivedSMS, "Report was not saved in classical report templates");
                Assert.IsNotNull(receivedSMS.ReportDatas, "Report data was not saved in classical report templates");

                var data = receivedSMS.ReportDatas;
                Assert.AreEqual(17, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual("04010100", data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(19, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(0, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(19, int.Parse(data[5].Data), "Indicator 3 is not saved well");
                Assert.AreEqual(20, int.Parse(data[6].Data), "Indicator 4 is not saved well");
                Assert.AreEqual(1, int.Parse(data[7].Data), "Indicator 5 is not saved well");
                Assert.AreEqual(20, int.Parse(data[8].Data), "Indicator 6 is not saved well");
                Assert.AreEqual(7, int.Parse(data[9].Data), "Indicator 7 is not saved well");
                Assert.AreEqual(0, int.Parse(data[10].Data), "Indicator 8 is not saved well");
                Assert.AreEqual(7, int.Parse(data[11].Data), "Indicator 9 is not saved well");
                Assert.AreEqual(7, int.Parse(data[12].Data), "Indicator 10 is not saved well");
                Assert.AreEqual(0, int.Parse(data[13].Data), "Indicator 11 is not saved well");
                Assert.AreEqual(0, int.Parse(data[14].Data), "Indicator 12 is not saved well");
                Assert.AreEqual(7, int.Parse(data[15].Data), "Indicator 13 is not saved well");
                Assert.AreEqual(1, int.Parse(data[16].Data), "Indicator 14 is not saved well"); 
            }
        }

        [TestMethod]
        public void Report_Processor_Is_Saving_Classical_PCR_Report()
        {
            string facilityCode = "04010100";
            int month = 1;
            int year = 2014;
            string reportKeyword = "PCR1";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},19,0,1,18,10,8,2,3,2,0,0,1",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            bool bActual = target.Submit();
            Assert.IsTrue(bActual, "Report is not saved - " + target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var receivedSMS = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == reportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(receivedSMS, "Report was not saved in classical report templates");
                Assert.IsNotNull(receivedSMS.ReportDatas, "Report data was not saved in classical report templates");

                var data = receivedSMS.ReportDatas;
                Assert.AreEqual(15, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual("04010100", data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(19, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(0, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(1, int.Parse(data[5].Data), "Indicator 3 is not saved well");
                Assert.AreEqual(18, int.Parse(data[6].Data), "Indicator 4 is not saved well");
                Assert.AreEqual(10, int.Parse(data[7].Data), "Indicator 5 is not saved well");
                Assert.AreEqual(8, int.Parse(data[8].Data), "Indicator 6 is not saved well");
                Assert.AreEqual(2, int.Parse(data[9].Data), "Indicator 7 is not saved well");
                Assert.AreEqual(3, int.Parse(data[10].Data), "Indicator 8 is not saved well");
                Assert.AreEqual(2, int.Parse(data[11].Data), "Indicator 9 is not saved well");
                Assert.AreEqual(0, int.Parse(data[12].Data), "Indicator 10 is not saved well");
                Assert.AreEqual(0, int.Parse(data[13].Data), "Indicator 11 is not saved well");
                Assert.AreEqual(1, int.Parse(data[14].Data), "Indicator 12 is not saved well");
            }
        }

        [TestMethod]
        public void Report_Processor_Is_Saving_Classical_MAT_Report()
        {
            string facilityCode = "04010100";
            int month = 1;
            int year = 2014;
            string reportKeyword = "MAT";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},19,0,1,18,10,8,2,3,2,0,0,1,0,3,0,1,2,1",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            bool bActual = target.Submit();
            Assert.IsTrue(bActual, "Report is not saved - " + target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var receivedSMS = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == reportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(receivedSMS, "Report was not saved in classical report templates");
                Assert.IsNotNull(receivedSMS.ReportDatas, "Report data was not saved in classical report templates");

                var data = receivedSMS.ReportDatas;
                Assert.AreEqual(21, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual("04010100", data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(19, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(0, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(1, int.Parse(data[5].Data), "Indicator 3 is not saved well");
                Assert.AreEqual(18, int.Parse(data[6].Data), "Indicator 4 is not saved well");
                Assert.AreEqual(10, int.Parse(data[7].Data), "Indicator 5 is not saved well");
                Assert.AreEqual(8, int.Parse(data[8].Data), "Indicator 6 is not saved well");
                Assert.AreEqual(2, int.Parse(data[9].Data), "Indicator 7 is not saved well");
                Assert.AreEqual(3, int.Parse(data[10].Data), "Indicator 8 is not saved well");
                Assert.AreEqual(2, int.Parse(data[11].Data), "Indicator 9 is not saved well");
                Assert.AreEqual(0, int.Parse(data[12].Data), "Indicator 10 is not saved well");
                Assert.AreEqual(0, int.Parse(data[13].Data), "Indicator 11 is not saved well");
                Assert.AreEqual(1, int.Parse(data[14].Data), "Indicator 12 is not saved well");
                Assert.AreEqual(0, int.Parse(data[15].Data), "Indicator 13 is not saved well");
                Assert.AreEqual(3, int.Parse(data[16].Data), "Indicator 14 is not saved well");
                Assert.AreEqual(0, int.Parse(data[17].Data), "Indicator 15 is not saved well");
                Assert.AreEqual(1, int.Parse(data[18].Data), "Indicator 16 is not saved well");
                Assert.AreEqual(2, int.Parse(data[19].Data), "Indicator 17 is not saved well");
                Assert.AreEqual(1, int.Parse(data[20].Data), "Indicator 18 is not saved well");
            }
        }

        [TestMethod]
        public void Report_Processor_Is_Saving_Classical_MC_Report()
        {
            string facilityCode = "04010100";
            int month = 1;
            int year = 2014;
            string reportKeyword = "MC";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},18,0,1,18,10,8,2,3,2,0,0,1,0,3,0,1,2,1,0,0",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            bool bActual = target.Submit();
            Assert.IsTrue(bActual, "Report is not saved - " + target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var receivedSMS = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == reportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(receivedSMS, "Report was not saved in classical report templates");
                Assert.IsNotNull(receivedSMS.ReportDatas, "Report data was not saved in classical report templates");

                var data = receivedSMS.ReportDatas;
                Assert.AreEqual(23, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual("04010100", data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(18, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(0, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(1, int.Parse(data[5].Data), "Indicator 3 is not saved well");
                Assert.AreEqual(18, int.Parse(data[6].Data), "Indicator 4 is not saved well");
                Assert.AreEqual(10, int.Parse(data[7].Data), "Indicator 5 is not saved well");
                Assert.AreEqual(8, int.Parse(data[8].Data), "Indicator 6 is not saved well");
                Assert.AreEqual(2, int.Parse(data[9].Data), "Indicator 7 is not saved well");
                Assert.AreEqual(3, int.Parse(data[10].Data), "Indicator 8 is not saved well");
                Assert.AreEqual(2, int.Parse(data[11].Data), "Indicator 9 is not saved well");
                Assert.AreEqual(0, int.Parse(data[12].Data), "Indicator 10 is not saved well");
                Assert.AreEqual(0, int.Parse(data[13].Data), "Indicator 11 is not saved well");
                Assert.AreEqual(1, int.Parse(data[14].Data), "Indicator 12 is not saved well");
                Assert.AreEqual(0, int.Parse(data[15].Data), "Indicator 13 is not saved well");
                Assert.AreEqual(3, int.Parse(data[16].Data), "Indicator 14 is not saved well");
                Assert.AreEqual(0, int.Parse(data[17].Data), "Indicator 15 is not saved well");
                Assert.AreEqual(1, int.Parse(data[18].Data), "Indicator 16 is not saved well");
                Assert.AreEqual(2, int.Parse(data[19].Data), "Indicator 17 is not saved well");
                Assert.AreEqual(1, int.Parse(data[20].Data), "Indicator 18 is not saved well");
                Assert.AreEqual(0, int.Parse(data[21].Data), "Indicator 20 is not saved well");
                Assert.AreEqual(0, int.Parse(data[22].Data), "Indicator 21 is not saved well");
            }
        }

        [TestMethod]
        public void Report_Processor_Is_Saving_TestKit_Report_Classic_Format()
        {
            string facilityCode = "04010100";
            int month = 1;
            int year = 2014;
            string reportKeyword = "TK";

            AppConfiguration.EnableStockInformation = true;
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},19,10,13",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            bool bActual = target.Submit();
            Assert.IsTrue(bActual, "Report is not saved - " + target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var receivedSMS = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == reportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(receivedSMS, "Report was not saved in classical report templates");
                Assert.IsNotNull(receivedSMS.ReportDatas, "Report data was not saved in classical report templates");

                var data = receivedSMS.ReportDatas;
                Assert.AreEqual(6, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual("04010100", data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(19, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(10, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(13, int.Parse(data[5].Data), "Indicator 3 is not saved well");

                var stockData = (from r in db.StockStatus
                                 where r.FacCode == facilityCode &&
                                 r.ReportMonth == month && r.ReportYear == year
                                 select r).FirstOrDefault();

                Assert.IsNotNull(stockData, "TestKit Report was not saved");

                Assert.AreEqual(facilityCode, stockData.FacCode, "Facility code is not saved well");
                Assert.AreEqual(month, stockData.ReportMonth, "Report month is not saved well");
                Assert.AreEqual(year, stockData.ReportYear, "Report year is not saved well");
                Assert.AreEqual(13, stockData.RequiredDBS, "DBS is not saved well");
                Assert.AreEqual(10, stockData.RequiredUnigold, "Unigold is not saved well");
                Assert.AreEqual(19, stockData.RequiredDetermine, "Determine is not saved well");
            }
        }

        [TestMethod]
        public void ANC_Report_Is_Valid_Ending_With_Comma_Flexible_Mode()
        {
            string reportingText = "ANC1.04010100,1,2014,1,2,3,4,5,6,7,8,9,10,11,12,13,14,";
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.FLEXIBLE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);

            Assert.AreEqual("04010100", target.FacilityCode, target.ErrorText);
            Assert.AreEqual(1, target.Period, target.ErrorText);
            Assert.AreEqual(2014, target.Year, target.ErrorText);

            var data = target.ReportData;
            Assert.AreEqual(14, data.Count, target.ErrorText);
        }

        [TestMethod]
        public void ANC_Report_Is_Valid_Ending_With_Period_Flexible_Mode()
        {
            string reportingText = "ANC1.04010100,1,2014,1,2,3,4,5,6,7,8,9,10,11,12,13,14.";
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.FLEXIBLE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);

            Assert.AreEqual("04010100", target.FacilityCode, target.ErrorText);
            Assert.AreEqual(1, target.Period, target.ErrorText);
            Assert.AreEqual(2014, target.Year, target.ErrorText);

            var data = target.ReportData;
            Assert.AreEqual(14, data.Count, target.ErrorText);
        }

        [TestMethod]
        public void ANC_Report_Is_Valid_With_Period_Comma_In_Between()
        {
            string reportingText = "ANC1.04010100,1.2014,1,2,3,4,5.6,7,,8,9,10,11,12,13,14.";
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.FLEXIBLE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);

            Assert.AreEqual("04010100", target.FacilityCode, target.ErrorText);
            Assert.AreEqual(1, target.Period, target.ErrorText);
            Assert.AreEqual(2014, target.Year, target.ErrorText);

            var data = target.ReportData;
            Assert.AreEqual(14, data.Count, target.ErrorText);

            Assert.AreEqual(1, data[0]);
            Assert.AreEqual(2, data[1]);
            Assert.AreEqual(3, data[2]);
            Assert.AreEqual(4, data[3]);
            Assert.AreEqual(5, data[4]);
            Assert.AreEqual(6, data[5]);
            Assert.AreEqual(7, data[6]);
            Assert.AreEqual(8, data[7]);
            Assert.AreEqual(9, data[8]);
            Assert.AreEqual(10, data[9]);
            Assert.AreEqual(11, data[10]);
            Assert.AreEqual(12, data[11]);
            Assert.AreEqual(13, data[12]);
            Assert.AreEqual(14, data[13]);
        }

        [TestMethod]
        public void Report_Keyword_Is_Followed_By_Comma_In_Flexible_Mode()
        {
            string reportingText = "ANC1,04010100,1,2014,1,2,3,4,5.6,7,,8,9,10,11,12,13,14.";
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.FLEXIBLE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);

            Assert.AreEqual("04010100", target.FacilityCode, target.ErrorText);
            Assert.AreEqual(1, target.Period, target.ErrorText);
            Assert.AreEqual(2014, target.Year, target.ErrorText);

            var data = target.ReportData;
            Assert.AreEqual(14, data.Count, target.ErrorText);
            Assert.AreEqual(1, data[0]);
            Assert.AreEqual(2, data[1]);
            Assert.AreEqual(3, data[2]);
            Assert.AreEqual(4, data[3]);
            Assert.AreEqual(5, data[4]);
            Assert.AreEqual(6, data[5]);
            Assert.AreEqual(7, data[6]);
            Assert.AreEqual(8, data[7]);
            Assert.AreEqual(9, data[8]);
            Assert.AreEqual(10, data[9]);
            Assert.AreEqual(11, data[10]);
            Assert.AreEqual(12, data[11]);
            Assert.AreEqual(13, data[12]);
            Assert.AreEqual(14, data[13]);
        }

        [TestMethod]
        public void Report_Processor_Is_Given_MTUHA_Report()
        {
            TestDataInitializer.TruncateRelatedOptionBPlusTables();

            string reportingText = "ANC.04010100,1,2014,C20,K5,1,10,7,2,5,1,10,7,3,0,7,1,1,1,1,1,2";
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);

            Assert.IsTrue(target.HasError, target.ErrorText);
            Assert.IsTrue(target.Submit(), target.ErrorText);
            Assert.IsFalse(target.HasError, target.ErrorText);

            Assert.AreEqual("04010100", target.FacilityCode, target.ErrorText);
            Assert.AreEqual(1, target.Period, target.ErrorText);
            Assert.AreEqual(2014, target.Year, target.ErrorText);
        }

        [TestMethod]
        [Owner("IQSMS Log")]
        public void Report_Processor_Is_Given_Very_Short_Invalid_Text()
        {
            string reportingText = ".";
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);

            Assert.IsTrue(target.HasError, target.ErrorText);
            Assert.AreEqual(ReportingError.INVALID_REPORT_INITIALIZATION_LABEL, target.ErrorTextLabelID, target.ErrorTextLabelID);
        }

        [TestMethod]
        public void Processor_Is_Given_Loosely_MTUHA_Report_In_Flexible_Mode()
        {
            TestDataInitializer.TruncateRelatedOptionBPlusTables();

            string reportingText = "ANC,04010100,1,2014,C20,K5,1,10,7,2,5,1,10,7,3,0,7,1,1,1,1,1,2,";
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);

            Assert.IsTrue(target.HasError, target.ErrorText);
            Assert.IsTrue(target.Submit(), target.ErrorText);
            Assert.IsFalse(target.HasError, target.ErrorText);

            Assert.AreEqual("04010100", target.FacilityCode, target.ErrorText);
            Assert.AreEqual(1, target.Period, target.ErrorText);
            Assert.AreEqual(2014, target.Year, target.ErrorText);
        }

        [TestMethod]
        public void Report_Processor_Given_Testing_Kits_Report()
        {
            string reportingText = "1,2014,dt5,un10,dbs30";
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var processor = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);

            Assert.IsTrue(processor.HasError, "Report Processor accepts invalid stock report format");

            bool bActual = default(bool);
            var error = ReportingError.GetReportingError(ReportProcessingError.NO_ERROR, phoneNumber);
            string sExpected = error.ErrorText;
            var reportingError = ReportProcessor.ProcessStockReportingMessage(phoneNumber, reportingText,
                processor.ErrorText, processor.ErrorTextLabelID, out bActual);

            string sActual = reportingError.ErrorText;

            Assert.IsFalse(bActual, sActual);
            Assert.AreEqual(sExpected, sActual, sActual);     
        }

        [TestMethod]
        public void Report_Processor_Given_Testing_Kits_Report_Ending_With_Comma()
        {
            string reportingText = "1,2014,dt5,un10,dbs30,";
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var processor = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);

            Assert.IsTrue(processor.HasError, "Report Processor accepts invalid stock report format");

            bool bActual = default(bool);
            var error = ReportingError.GetReportingError(ReportProcessingError.NO_ERROR, phoneNumber);
            string sExpected = error.ErrorText;
            var reportingError = ReportProcessor.ProcessStockReportingMessage(phoneNumber, reportingText,
                processor.ErrorText, processor.ErrorTextLabelID, out bActual);
            string sActual = reportingError.ErrorText;

            Assert.IsFalse(bActual, sActual);
            Assert.AreEqual(sExpected, sActual, sActual);
        }

        [TestMethod]
        public void Report_Processor_Given_Testing_Kits_Report_Ending_With_Period()
        {
            string reportingText = "1,2014,dt5,un10,dbs30.";
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var processor = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);

            Assert.IsTrue(processor.HasError, "Report Processor accepts invalid stock report format");

            bool bActual = default(bool);
            var error = ReportingError.GetReportingError(ReportProcessingError.NO_ERROR, phoneNumber);
            string sExpected = error.ErrorText;
            var reportingError = ReportProcessor.ProcessStockReportingMessage(phoneNumber, reportingText,
                processor.ErrorText, processor.ErrorTextLabelID, out bActual);
            string sActual = reportingError.ErrorText;

            Assert.IsFalse(bActual, sActual);
            Assert.AreEqual(sExpected, sActual, sActual);
        }

        [TestMethod]
        public void Report_Processor_Given_Testing_Kits_Report_With_Commas_In_Between()
        {
            string reportingText = "1.2014.dt5.un10.dbs30.";
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var processor = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);

            Assert.IsTrue(processor.HasError, "Report Processor accepts invalid stock report format");

            bool bActual = default(bool);
            var error = ReportingError.GetReportingError(ReportProcessingError.NO_ERROR, phoneNumber);
            string sExpected = error.ErrorText;
            var reportingError = ReportProcessor.ProcessStockReportingMessage(phoneNumber, reportingText,
                processor.ErrorText, processor.ErrorTextLabelID, out bActual);
            string sActual = reportingError.ErrorText;

            Assert.IsFalse(bActual, sActual, sActual);
            Assert.AreEqual(sExpected, sActual, sActual);
        }

        [TestMethod]
        public void Report_Processor_Given_Testing_Kits_Report_Mixed_With_Commas_And_Periods()
        {
            string reportingText = "1.2014.dt5,un10.,dbs30.";
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var processor = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);

            Assert.IsTrue(processor.HasError, "Report Processor accepts invalid stock report format");

            bool bActual = default(bool);
            var error = ReportingError.GetReportingError(ReportProcessingError.NO_ERROR, phoneNumber);
            string sExpected = error.ErrorText;
            var reportingError = ReportProcessor.ProcessStockReportingMessage(phoneNumber, reportingText,
                processor.ErrorText, processor.ErrorTextLabelID, out bActual);
            string sActual = reportingError.ErrorText;

            Assert.IsFalse(bActual, sActual, sActual);
            Assert.AreEqual(sExpected, sActual, sActual);
        }

        [TestMethod]
        public void TestKit_Processor_Given_Invalid_PMTCT_Report()
        {
            string reportingText = "ANC,04010100,1,2014,1,2,3,4,5.6,7,,8,9,10,11,12,13,14.";
            string phoneNumber = "+255763986451";

            AppConfiguration.EnableStockInformation = true;
            SMSReportingFormat format = SMSReportingFormat.FLEXIBLE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;

            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            string sExpected = target.ErrorText;

            Assert.IsTrue(target.HasError, "Set a condition which will generate errors");

            bool bExpected = true;
            bool bActual = default(bool);
            var reportingError = ReportProcessor.ProcessStockReportingMessage(phoneNumber, reportingText,
                sExpected, target.ErrorTextLabelID, out bActual);
            string sActual = reportingError.ErrorText;

            Assert.AreEqual(bExpected, bActual, sActual);
            Assert.AreEqual(sExpected, sActual, sActual);
        }

        [TestMethod]
        public void ANC_Report_Is_Valid_With_Month_Text_Flexible_Mode()
        {
            string reportingText = "ANC1.04010100,Jan.2014,1,2,3,4,5,6,7,8,9,10,11,12,13,14";
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.FLEXIBLE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);

            Assert.AreEqual("04010100", target.FacilityCode, target.ErrorText);
            Assert.AreEqual(1, target.Period, target.ErrorText);
            Assert.AreEqual(2014, target.Year, target.ErrorText);

            var data = target.ReportData;
            Assert.AreEqual(14, data.Count, target.ErrorText);
            Assert.AreEqual(1, data[0]);
            Assert.AreEqual(2, data[1]);
            Assert.AreEqual(3, data[2]);
            Assert.AreEqual(4, data[3]);
            Assert.AreEqual(5, data[4]);
            Assert.AreEqual(6, data[5]);
            Assert.AreEqual(7, data[6]);
            Assert.AreEqual(8, data[7]);
            Assert.AreEqual(9, data[8]);
            Assert.AreEqual(10, data[9]);
            Assert.AreEqual(11, data[10]);
            Assert.AreEqual(12, data[11]);
            Assert.AreEqual(13, data[12]);
            Assert.AreEqual(14, data[13]);
        }

        [TestMethod]
        public void MTUHA_Report_In_Class_Format_Is_Saved()
        {
            string phoneNumber = "12345";
            string facilityCode = "04010100";
            string reportKeyword = "K1C20";
            int month = 10;
            int year = 2013;
            var ageCategory = MTUHAAgeCategory.UNDER_20_YEARS;
            string reportingText = string.Format("{0}.{1},{2},{3},3", 
                reportKeyword, facilityCode, month, year);
            SMSReportingFormat format = SMSReportingFormat.FLEXIBLE;
            ReportingMode mode = ReportingMode.DEFAULT | ReportingMode.IGNORE_EXPECTED_REPORTS;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;

            TestDataInitializer.TryToRegisterUser(phoneNumber, facilityCode);
            TestDataInitializer.TruncateRelatedOptionBPlusTables();
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year); 

            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            bool bActual = target.Submit();
            Assert.IsTrue(bActual, target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var mtuha = (from r in db.ANCForms
                             where r.FacilityCode == facilityCode &&
                             r.Month == month && r.Year == year &&
                             r.LessThan20 == (ageCategory == MTUHAAgeCategory.UNDER_20_YEARS)
                             select r).FirstOrDefault();

                Assert.IsNotNull(mtuha, "Report is not saved at all");
                Assert.IsNotNull(mtuha.C_1, "Report exists, but data is not saved at all");
                Assert.AreEqual(3, mtuha.C_1, "Report is not saved properly");
            }
        }

        [TestMethod]
        public void ANC_Automatic_Handling_Of_Report_Versions()
        {
            string facilityCode = "04020110";
            int month = 3;
            int year = 2014;
            string reportKeyword = "ANC1";
            string anotherReportKeyword = "ANC";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},19,0,19,20,1,20,7,0,7,7,0,0,7,1",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255782162298";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT | ReportingMode.ALLOW_SAME_MONTH_REPORTING;
            
            bool previousValue = AppConfiguration.SameMonthReporting;
            AppConfiguration.SameMonthReporting = true;

            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            bool bActual = target.Submit();
            Assert.IsTrue(bActual, "Report is not saved");

            using (var db = new IQSMS_TestDBContext())
            {
                var receivedSMS = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == anotherReportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(receivedSMS, "Report was not saved in classical report templates");
                Assert.IsNotNull(receivedSMS.ReportDatas, "Report data was not saved in classical report templates");

                var data = receivedSMS.ReportDatas;
                Assert.AreEqual(17, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual(facilityCode, data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(19, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(0, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(19, int.Parse(data[5].Data), "Indicator 3 is not saved well");
                Assert.AreEqual(20, int.Parse(data[6].Data), "Indicator 4 is not saved well");
                Assert.AreEqual(1, int.Parse(data[7].Data), "Indicator 5 is not saved well");
                Assert.AreEqual(7, int.Parse(data[8].Data), "Indicator 6 is not saved well");       // ANC06
                Assert.AreEqual(0, int.Parse(data[9].Data), "Indicator 7 is not saved well");       // ANC07
                Assert.AreEqual(20, int.Parse(data[10].Data), "Indicator 8 is not saved well");     // ANC08
                Assert.AreEqual(7, int.Parse(data[11].Data), "Indicator 9 is not saved well");
                Assert.AreEqual(7, int.Parse(data[12].Data), "Indicator 10 is not saved well");
                Assert.AreEqual(0, int.Parse(data[13].Data), "Indicator 11 is not saved well");
                Assert.AreEqual(0, int.Parse(data[14].Data), "Indicator 12 is not saved well");
                Assert.AreEqual(7, int.Parse(data[15].Data), "Indicator 13 is not saved well");
                Assert.AreEqual(1, int.Parse(data[16].Data), "Indicator 14 is not saved well");
            }

            // Restore previous state
            AppConfiguration.SameMonthReporting = previousValue;
        }

        [TestMethod]
        public void Report_Processor_Given_PCR1()
        {
            string facilityCode = "04020110";
            int month = 3;
            int year = 2014;
            string reportKeyword = "PCR1";
            string anotherReportKeyword = "PCR";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},2,1,2,0,2,0,0,0,2,0,0,0",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255782162298";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT | ReportingMode.ALLOW_SAME_MONTH_REPORTING;

            bool previousValue = AppConfiguration.SameMonthReporting;
            AppConfiguration.SameMonthReporting = true;

            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            bool bActual = target.Submit();
            Assert.IsTrue(bActual, "Report is not saved - " + target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var receivedSMS = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == anotherReportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(receivedSMS, "Report was not saved in classical report templates");
                Assert.IsNotNull(receivedSMS.ReportDatas, "Report data was not saved in classical report templates");

                var data = receivedSMS.ReportDatas;
                Assert.AreEqual(16, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual(facilityCode, data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(2, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(1, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(2, int.Parse(data[5].Data), "Indicator 3 is not saved well");
                Assert.AreEqual(0, int.Parse(data[6].Data), "Indicator 4 is not saved well");
                Assert.AreEqual(2, int.Parse(data[7].Data), "Indicator 5 is not saved well");
                Assert.AreEqual(0, int.Parse(data[8].Data), "Indicator 6 is not saved well");       // ANC06
                Assert.AreEqual(0, int.Parse(data[9].Data), "Indicator 7 is not saved well");       // ANC07
                Assert.AreEqual(0, int.Parse(data[10].Data), "Indicator 8 is not saved well");     // ANC08
                Assert.AreEqual(2, int.Parse(data[11].Data), "Indicator 9 is not saved well");
                Assert.AreEqual(0, int.Parse(data[12].Data), "Indicator 10 is not saved well");
                Assert.AreEqual(0, int.Parse(data[13].Data), "Indicator 11 is not saved well");
                Assert.AreEqual(0, int.Parse(data[14].Data), "Indicator 12 is not saved well");
            }

            // Restore previous state
            AppConfiguration.SameMonthReporting = previousValue;
        }

        [TestMethod]
        public void Report_Processor_Given_Classical_MAT()
        {
            string facilityCode = "04020110";
            int month = 3;
            int year = 2014;
            string reportKeyword = "MAT";
            string anotherReportKeyword = "MAT";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255782162298";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT | ReportingMode.ALLOW_SAME_MONTH_REPORTING;

            bool previousValue = AppConfiguration.SameMonthReporting;
            AppConfiguration.SameMonthReporting = true;

            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            bool bActual = target.Submit();
            Assert.IsTrue(bActual, "Report is not saved - " + target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var receivedSMS = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == anotherReportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(receivedSMS, "Report was not saved in classical report templates");
                Assert.IsNotNull(receivedSMS.ReportDatas, "Report data was not saved in classical report templates");

                var data = receivedSMS.ReportDatas;
                Assert.AreEqual(21, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual(facilityCode, data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(8, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(8, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(0, int.Parse(data[5].Data), "Indicator 3 is not saved well");
                Assert.AreEqual(0, int.Parse(data[6].Data), "Indicator 4 is not saved well");
                Assert.AreEqual(0, int.Parse(data[7].Data), "Indicator 5 is not saved well");
                Assert.AreEqual(0, int.Parse(data[8].Data), "Indicator 6 is not saved well");       // ANC06
                Assert.AreEqual(0, int.Parse(data[9].Data), "Indicator 7 is not saved well");       // ANC07
                Assert.AreEqual(0, int.Parse(data[10].Data), "Indicator 8 is not saved well");     // ANC08
                Assert.AreEqual(0, int.Parse(data[11].Data), "Indicator 9 is not saved well");
                Assert.AreEqual(0, int.Parse(data[12].Data), "Indicator 10 is not saved well");
                Assert.AreEqual(0, int.Parse(data[13].Data), "Indicator 11 is not saved well");
                Assert.AreEqual(0, int.Parse(data[14].Data), "Indicator 12 is not saved well");
                Assert.AreEqual(0, int.Parse(data[15].Data), "Indicator 13 is not saved well");
                Assert.AreEqual(0, int.Parse(data[16].Data), "Indicator 14 is not saved well");
                Assert.AreEqual(0, int.Parse(data[17].Data), "Indicator 15 is not saved well");
                Assert.AreEqual(0, int.Parse(data[18].Data), "Indicator 16 is not saved well");
                Assert.AreEqual(0, int.Parse(data[19].Data), "Indicator 17 is not saved well");
                Assert.AreEqual(0, int.Parse(data[20].Data), "Indicator 18 is not saved well");
            }

            // Restore previous state
            AppConfiguration.SameMonthReporting = previousValue;
        }

        [TestMethod]
        [Owner("Rahabu Wanjara")]
        public void Report_Processor_Given_Classical_MC_With_Quarter_End_Period()
        {
            string facilityCode = "04020110";
            int month = 6;
            int year = 2014;
            string reportKeyword = "MC";
            string anotherReportKeyword = "MC";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},18,0,1,18,10,8,2,3,2,0,0,1,0,3,0,1,2,1,0,0",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255782162298";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT | ReportingMode.ALLOW_SAME_MONTH_REPORTING;

            bool previousValue = AppConfiguration.SameMonthReporting;
            AppConfiguration.SameMonthReporting = true;

            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            target.ReportBussinessRulesFailed += ReportProcessor.HandleMTUHAMCReport;

            bool bActual = target.Submit();
            Assert.IsTrue(bActual, "Report is not saved - " + target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var receivedSMS = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == anotherReportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(receivedSMS, "Report was not saved in classical report templates");
                Assert.IsNotNull(receivedSMS.ReportDatas, "Report data was not saved in classical report templates");

                var data = receivedSMS.ReportDatas;
                Assert.AreEqual(23, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual(facilityCode, data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(18, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(0, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(1, int.Parse(data[5].Data), "Indicator 3 is not saved well");
                Assert.AreEqual(18, int.Parse(data[6].Data), "Indicator 4 is not saved well");
                Assert.AreEqual(10, int.Parse(data[7].Data), "Indicator 5 is not saved well");
                Assert.AreEqual(8, int.Parse(data[8].Data), "Indicator 6 is not saved well");
                Assert.AreEqual(2, int.Parse(data[9].Data), "Indicator 7 is not saved well");
                Assert.AreEqual(3, int.Parse(data[10].Data), "Indicator 8 is not saved well");
                Assert.AreEqual(2, int.Parse(data[11].Data), "Indicator 9 is not saved well");
                Assert.AreEqual(0, int.Parse(data[12].Data), "Indicator 10 is not saved well");
                Assert.AreEqual(0, int.Parse(data[13].Data), "Indicator 11 is not saved well");
                Assert.AreEqual(1, int.Parse(data[14].Data), "Indicator 12 is not saved well");
                Assert.AreEqual(0, int.Parse(data[15].Data), "Indicator 13 is not saved well");
                Assert.AreEqual(3, int.Parse(data[16].Data), "Indicator 14 is not saved well");
                Assert.AreEqual(0, int.Parse(data[17].Data), "Indicator 15 is not saved well");
                Assert.AreEqual(1, int.Parse(data[18].Data), "Indicator 16 is not saved well");
                Assert.AreEqual(2, int.Parse(data[19].Data), "Indicator 17 is not saved well");
                Assert.AreEqual(1, int.Parse(data[20].Data), "Indicator 18 is not saved well");
                Assert.AreEqual(0, int.Parse(data[21].Data), "Indicator 20 is not saved well");
                Assert.AreEqual(0, int.Parse(data[22].Data), "Indicator 21 is not saved well");
            }

            // Restore previous state
            AppConfiguration.SameMonthReporting = previousValue;
        }

        [TestMethod]
        [Owner("Rahabu Wanjara")]
        public void Report_Processor_Given_Classical_MC_Business_Rules_Observed_Not_Mistreated_As_MTUHA_MC()
        {
            string facilityCode = "04020110";
            int month = 6;
            int year = 2014;
            string reportKeyword = "MC";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},1,8,1,18,10,8,2,3,2,0,0,1,0,3,0,1,2,1,0,0",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255782162298";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT | ReportingMode.ALLOW_SAME_MONTH_REPORTING;

            bool previousValue = AppConfiguration.SameMonthReporting;
            AppConfiguration.SameMonthReporting = true;

            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            target.ReportBussinessRulesFailed += ReportProcessor.HandleMTUHAMCReport;

            bool bActual = target.Submit();
            Assert.IsFalse(bActual, "Report should not be saved - " + target.ErrorText);

            var iExpected = ReportingError.BUSINESS_RULES_FAILURE_LABEL;
            Assert.AreEqual(iExpected, target.ErrorTextLabelID, target.ErrorTextLabelID);
            
            iExpected = ReportingError.MANY_REPORT_PARAMETERS_LABEL;
            Assert.AreNotEqual(iExpected, target.ErrorTextLabelID, target.ErrorTextLabelID);
        }

        [TestMethod]
        public void Report_Processor_Given_MAT_With_Invalid_Year()
        {
            string facilityCode = "04020110";
            int month = 3;
            int year = 20014;
            string reportKeyword = "MAT";
            string anotherReportKeyword = "MAT";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255782162298";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT | ReportingMode.ALLOW_SAME_MONTH_REPORTING;

            bool previousValue = AppConfiguration.SameMonthReporting;
            AppConfiguration.SameMonthReporting = true;

            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            bool bActual = target.Submit();
            Assert.IsFalse(bActual, "Report is not saved - " + target.ErrorText);

            int iActual = target.ErrorTextLabelID;
            int iExpected = ReportingError.REPORT_HAS_FUTURE_RECORDS_LABEL;
            Assert.AreEqual(iActual, iExpected, target.ErrorTextLabelID.ToString());

            // Restore previous state
            AppConfiguration.SameMonthReporting = previousValue;
        }

        [TestMethod]
        public void Report_Processor_Given_Classical_MAT_With_Invalid_Logic()
        {
            string facilityCode = "04020110";
            int month = 3;
            int year = 2014;
            string reportKeyword = "MAT";
            string anotherReportKeyword = "MAT";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},8,8,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255782162298";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT | ReportingMode.ALLOW_SAME_MONTH_REPORTING;

            bool previousValue = AppConfiguration.SameMonthReporting;
            AppConfiguration.SameMonthReporting = true;

            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            target.ReportBussinessRulesFailed += target_ReportBussinessRulesFailed;

            bool bActual = target.Submit();
            Assert.IsTrue(bActual, "Report is not saved - " + target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var receivedSMS = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == anotherReportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(receivedSMS, "Report was not saved in classical report templates");
                Assert.IsNotNull(receivedSMS.ReportDatas, "Report data was not saved in classical report templates");

                var data = receivedSMS.ReportDatas;
                Assert.AreEqual(21, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual(facilityCode, data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(8, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(8, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(0, int.Parse(data[5].Data), "Indicator 3 is not saved well");
                Assert.AreEqual(0, int.Parse(data[6].Data), "Indicator 4 is not saved well");
                Assert.AreEqual(0, int.Parse(data[7].Data), "Indicator 5 is not saved well");
                Assert.AreEqual(0, int.Parse(data[8].Data), "Indicator 6 is not saved well");       // ANC06
                Assert.AreEqual(0, int.Parse(data[9].Data), "Indicator 7 is not saved well");       // ANC07
                Assert.AreEqual(0, int.Parse(data[10].Data), "Indicator 8 is not saved well");     // ANC08
                Assert.AreEqual(0, int.Parse(data[11].Data), "Indicator 9 is not saved well");
                Assert.AreEqual(0, int.Parse(data[12].Data), "Indicator 10 is not saved well");
                Assert.AreEqual(0, int.Parse(data[13].Data), "Indicator 11 is not saved well");
                Assert.AreEqual(0, int.Parse(data[14].Data), "Indicator 12 is not saved well");
                Assert.AreEqual(0, int.Parse(data[15].Data), "Indicator 13 is not saved well");
                Assert.AreEqual(0, int.Parse(data[16].Data), "Indicator 14 is not saved well");
                Assert.AreEqual(0, int.Parse(data[17].Data), "Indicator 15 is not saved well");
                Assert.AreEqual(0, int.Parse(data[18].Data), "Indicator 16 is not saved well");
                Assert.AreEqual(0, int.Parse(data[19].Data), "Indicator 17 is not saved well");
                Assert.AreEqual(0, int.Parse(data[20].Data), "Indicator 18 is not saved well");
            }

            // Restore previous state
            AppConfiguration.SameMonthReporting = previousValue;
        }

        void target_ReportBussinessRulesFailed(object sender, ReportProcessorEventArgs e)
        {
            e.ResolvedDataElements[16] = "0";
            e.ReEvaluate = true;
        }

        [TestMethod]
        public void Report_Processor_Is_Saving_MTUHA_MC_Report_Not_Quarterly_Based()
        {
            string facilityCode = "04010100";
            int month = 1;
            int year = 2014;
            string reportKeyword = "MC";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},18,0,1,18,10,8,2,3,2,0,0,1,0,3,0,1,2,1,0",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            target.ReportBussinessRulesFailed += ReportProcessor.HandleMTUHAMCReport;

            bool bActual = target.Submit();
            Assert.IsFalse(bActual, target.ErrorText);

            var iExpected = ReportingError.MTUHA_REPORT_MC_IS_QUARTERLY_REPORTED_LABEL;
            var iActual = target.ErrorTextLabelID;
            Assert.AreEqual(iExpected, iActual, target.ErrorText);
        }

        [TestMethod]
        public void Report_Processor_Is_Saving_MTUHA_MC_Report_In_Quarterly_Based()
        {
            string facilityCode = "04010100";
            int month = 3;
            int year = 2014;
            string reportKeyword = "MC";
            string MCReportKeyword = "MTMC";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);
            TestDataInitializer.RemoveReportIfExists(facilityCode, MCReportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},18,0,1,18,10,8,2,3,2,0,0,1,0,3,0,1,2,1,0",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;

            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            target.ReportBussinessRulesFailed += ReportProcessor.HandleMTUHAMCReport;

            bool bActual = target.Submit();
            Assert.IsTrue(bActual, "Report is not saved - " + target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var receivedSMS = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == MCReportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(receivedSMS, "Report was not saved in classical report templates");
                Assert.IsNotNull(receivedSMS.ReportDatas, "Report data was not saved in classical report templates");

                var data = receivedSMS.ReportDatas;
                Assert.AreEqual(22, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual("04010100", data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(18, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(0, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(1, int.Parse(data[5].Data), "Indicator 3 is not saved well");
                Assert.AreEqual(18, int.Parse(data[6].Data), "Indicator 4 is not saved well");
                Assert.AreEqual(10, int.Parse(data[7].Data), "Indicator 5 is not saved well");
                Assert.AreEqual(8, int.Parse(data[8].Data), "Indicator 6 is not saved well");
                Assert.AreEqual(2, int.Parse(data[9].Data), "Indicator 7 is not saved well");
                Assert.AreEqual(3, int.Parse(data[10].Data), "Indicator 8 is not saved well");
                Assert.AreEqual(2, int.Parse(data[11].Data), "Indicator 9 is not saved well");
                Assert.AreEqual(0, int.Parse(data[12].Data), "Indicator 10 is not saved well");
                Assert.AreEqual(0, int.Parse(data[13].Data), "Indicator 11 is not saved well");
                Assert.AreEqual(1, int.Parse(data[14].Data), "Indicator 12 is not saved well");
                Assert.AreEqual(0, int.Parse(data[15].Data), "Indicator 13 is not saved well");
                Assert.AreEqual(3, int.Parse(data[16].Data), "Indicator 14 is not saved well");
                Assert.AreEqual(0, int.Parse(data[17].Data), "Indicator 15 is not saved well");
                Assert.AreEqual(1, int.Parse(data[18].Data), "Indicator 16 is not saved well");
                Assert.AreEqual(2, int.Parse(data[19].Data), "Indicator 17 is not saved well");
                Assert.AreEqual(1, int.Parse(data[20].Data), "Indicator 18 is not saved well");
                Assert.AreEqual(0, int.Parse(data[21].Data), "Indicator 20 is not saved well");
            }
        }

        [TestMethod]
        [Owner("Reporting Engine Log")]
        public void Report_Processor_Is_Saving_Classical_MC_Report_No_Period_Just_Commas()
        {
            string facilityCode = "04010100";
            int month = 5;
            int year = 2014;
            string reportKeyword = "MC";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0},{1},{2},{3},0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.HIGHLY_ADAPTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            bool bActual = target.Submit();
            Assert.IsTrue(bActual, "Report is not saved - " + target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var receivedSMS = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == reportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(receivedSMS, "Report was not saved in classical report templates");
                Assert.IsNotNull(receivedSMS.ReportDatas, "Report data was not saved in classical report templates");

                var data = receivedSMS.ReportDatas;
                Assert.AreEqual(23, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual("04010100", data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(0, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(0, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(0, int.Parse(data[5].Data), "Indicator 3 is not saved well");
                Assert.AreEqual(0, int.Parse(data[6].Data), "Indicator 4 is not saved well");
                Assert.AreEqual(0, int.Parse(data[7].Data), "Indicator 5 is not saved well");
                Assert.AreEqual(0, int.Parse(data[8].Data), "Indicator 6 is not saved well");
                Assert.AreEqual(0, int.Parse(data[9].Data), "Indicator 7 is not saved well");
                Assert.AreEqual(0, int.Parse(data[10].Data), "Indicator 8 is not saved well");
                Assert.AreEqual(0, int.Parse(data[11].Data), "Indicator 9 is not saved well");
                Assert.AreEqual(0, int.Parse(data[12].Data), "Indicator 10 is not saved well");
                Assert.AreEqual(0, int.Parse(data[13].Data), "Indicator 11 is not saved well");
                Assert.AreEqual(0, int.Parse(data[14].Data), "Indicator 12 is not saved well");
                Assert.AreEqual(0, int.Parse(data[15].Data), "Indicator 13 is not saved well");
                Assert.AreEqual(0, int.Parse(data[16].Data), "Indicator 14 is not saved well");
                Assert.AreEqual(0, int.Parse(data[17].Data), "Indicator 15 is not saved well");
                Assert.AreEqual(0, int.Parse(data[18].Data), "Indicator 16 is not saved well");
                Assert.AreEqual(0, int.Parse(data[19].Data), "Indicator 17 is not saved well");
                Assert.AreEqual(0, int.Parse(data[20].Data), "Indicator 18 is not saved well");
                Assert.AreEqual(0, int.Parse(data[21].Data), "Indicator 20 is not saved well");
                Assert.AreEqual(0, int.Parse(data[22].Data), "Indicator 21 is not saved well");
            }
        }

        [TestMethod]
        [Owner("Reporting Engine Log")]
        public void Report_Processor_Is_Saving_TestKit_Report()
        {
            string facilityCode = "04010100";
            int month = 4;
            int year = 2014;
            string reportKeyword = "TK";

            AppConfiguration.EnableStockInformation = true;
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0},{1},dbs0,uni14,dt33", month, year);
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.HIGHLY_ADAPTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            bool bActual = target.Submit();
            Assert.IsFalse(bActual, "The format testkit report has been accepted. WRONG!!!");

            bool hasError;
            var reportingError = ReportProcessor.ProcessStockReportingMessage(phoneNumber,
                                reportingText, target.ErrorText, target.ErrorTextLabelID,
                                out hasError, format);
            
            Assert.IsFalse(hasError, "The saving or processing operation of TestKit report failed");
            
            int iExpected = ReportingError.NO_ERROR_LABEL;
            int iActual = reportingError.Code;
            Assert.AreEqual(iExpected, iActual, reportingError.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var stockData = (from r in db.StockStatus
                                   where r.FacCode == facilityCode &&
                                   r.ReportMonth == month && r.ReportYear == year
                                   select r).FirstOrDefault();

                Assert.IsNotNull(stockData, "TestKit Report was not saved");

                Assert.AreEqual(facilityCode, stockData.FacCode, "Facility code is not saved well");
                Assert.AreEqual(month, stockData.ReportMonth, "Report month is not saved well");
                Assert.AreEqual(year, stockData.ReportYear, "Report year is not saved well");
                Assert.AreEqual(0, stockData.RequiredDBS, "DBS is not saved well");
                Assert.AreEqual(14, stockData.RequiredUnigold, "Unigold is not saved well");
                Assert.AreEqual(33, stockData.RequiredDetermine, "Determine is not saved well");

                var receivedSMS = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == reportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(receivedSMS, "Report was not saved in classical report templates");
                Assert.IsNotNull(receivedSMS.ReportDatas, "Report data was not saved in classical report templates");

                var data = receivedSMS.ReportDatas;
                Assert.AreEqual(6, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual(facilityCode, data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(33, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(14, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(0, int.Parse(data[5].Data), "Indicator 3 is not saved well");
            }
        }

        [TestMethod]
        [Owner("Reporting Engine Log")]
        public void Report_Processor_Is_Saving_Classical_MAT_Report_With_Excess_Parameter()
        {
            string facilityCode = "04010100";
            int month = 5;
            int year = 2014;
            string reportKeyword = "MAT";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = "MAT.04010100,5,2014,4,4,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0";
            string phoneNumber = "+255763986451";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;            
            
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            //DateTime justNow = DateTime.Now;
            bool bActual = target.Submit();
            Assert.IsFalse(bActual, "This report Report should not be saved - " + target.ErrorText);

            int iExpected = ReportingError.MANY_REPORT_PARAMETERS_LABEL;
            int iActual = target.ErrorTextLabelID;
            Assert.AreEqual(iExpected, iActual, target.ErrorText);

            //using (var db = new IQSMS_TestDBContext())
            //{
            //    var result = from e in db.ErrMsgSMS
            //                 where e.FacCode == facilityCode &&
            //                 e.SenderNum == phoneNumber && e.TxtDetails == reportingText
            //                 && e.Period == month && e.Year == year
            //                 && e.DateReceived >= justNow
            //                 select e;
                
            //    Assert.IsNotNull(result, "Results can not be null");

            //}
        }

        [TestMethod]
        [Owner("Lilian Zeramula")]
        public void Report_Processor_Handling_ANC_Mistakenly_For_ANC1()
        {
            string facilityCode = "04020110";
            int month = 3;
            int year = 2014;
            string reportKeyword = "ANC";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},20,2,15,16,1,16,5,0,5,16,0,16,15,1",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255782162298";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT | ReportingMode.ALLOW_SAME_MONTH_REPORTING;

            bool previousValue = AppConfiguration.SameMonthReporting;
            AppConfiguration.SameMonthReporting = true;

            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            target.SavingReport += ReportProcessor.HandleInconsitentReports;
            Assert.IsTrue(target.Submit(), target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var result = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == reportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(result, "Report was saved as it was. WRONG!!!");
                var data = result.ReportDatas;
                Assert.AreEqual(17, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual(facilityCode, data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(20, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(2, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(15, int.Parse(data[5].Data), "Indicator 3 is not saved well");
                Assert.AreEqual(16, int.Parse(data[6].Data), "Indicator 4 is not saved well");
                Assert.AreEqual(1, int.Parse(data[7].Data), "Indicator 5 is not saved well");
                Assert.AreEqual(5, int.Parse(data[8].Data), "Indicator 6 is not saved well");      // ANC06
                Assert.AreEqual(0, int.Parse(data[9].Data), "Indicator 7 is not saved well");       // ANC07
                Assert.AreEqual(16, int.Parse(data[10].Data), "Indicator 8 is not saved well");     // ANC08
                Assert.AreEqual(5, int.Parse(data[11].Data), "Indicator 9 is not saved well");
                Assert.AreEqual(16, int.Parse(data[12].Data), "Indicator 10 is not saved well");
                Assert.AreEqual(0, int.Parse(data[13].Data), "Indicator 11 is not saved well");
                Assert.AreEqual(16, int.Parse(data[14].Data), "Indicator 12 is not saved well");
                Assert.AreEqual(15, int.Parse(data[15].Data), "Indicator 10 is not saved well");
                Assert.AreEqual(1, int.Parse(data[16].Data), "Indicator 11 is not saved well");
            }
        }

        [TestMethod]
        [Owner("Lilian Zeramula")]
        public void Report_Processor_Handling_Correct_ANC_Not_Be_Mistakenly_For_ANC1()
        {
            string facilityCode = "04020110";
            int month = 3;
            int year = 2014;
            string reportKeyword = "ANC";
            TestDataInitializer.RemoveReportIfExists(facilityCode, reportKeyword, month, year);

            string reportingText = string.Format("{0}.{1},{2},{3},20,2,15,16,1,5,0,16,5,16,0,16,15,1",
                reportKeyword, facilityCode, month, year);
            string phoneNumber = "+255782162298";
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT | ReportingMode.ALLOW_SAME_MONTH_REPORTING;

            bool previousValue = AppConfiguration.SameMonthReporting;
            AppConfiguration.SameMonthReporting = true;

            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            var target = new ReportProcessor(phoneNumber, reportingText, mode, format, inputMethod);
            target.SavingReport += ReportProcessor.HandleInconsitentReports;
            Assert.IsTrue(target.Submit(), target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var receivedSMS = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == reportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(receivedSMS, "Report was not saved at all");
                Assert.IsNotNull(receivedSMS.ReportDatas, "Report data was not saved in classical report templates");

                var data = receivedSMS.ReportDatas;
                Assert.AreEqual(17, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual(facilityCode, data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(20, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(2, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(15, int.Parse(data[5].Data), "Indicator 3 is not saved well");
                Assert.AreEqual(16, int.Parse(data[6].Data), "Indicator 4 is not saved well");
                Assert.AreEqual(1, int.Parse(data[7].Data), "Indicator 5 is not saved well");
                Assert.AreEqual(5, int.Parse(data[8].Data), "Indicator 6 is not saved well");      // ANC06
                Assert.AreEqual(0, int.Parse(data[9].Data), "Indicator 7 is not saved well");       // ANC07
                Assert.AreEqual(16, int.Parse(data[10].Data), "Indicator 8 is not saved well");     // ANC08
                Assert.AreEqual(5, int.Parse(data[11].Data), "Indicator 9 is not saved well");
                Assert.AreEqual(16, int.Parse(data[12].Data), "Indicator 10 is not saved well");
                Assert.AreEqual(0, int.Parse(data[13].Data), "Indicator 11 is not saved well");
                Assert.AreEqual(16, int.Parse(data[14].Data), "Indicator 12 is not saved well");
                Assert.AreEqual(15, int.Parse(data[15].Data), "Indicator 10 is not saved well");
                Assert.AreEqual(1, int.Parse(data[16].Data), "Indicator 11 is not saved well");
            }
        }

        [TestMethod]
        [Owner("Lilian Zeramula")]
        public void Report_Processor_Is_Given_MTUHA_MAT_Report()
        {
            //AppConfiguration.DBConnectionString = @"Data Source=41.73.195.220\SQL2008R2;Initial Catalog=IQSMS_TestDB;User ID=sa;Password=c0nstella";          
            string phoneNumber = "++255784488124";
            string facilityCode = "04050100";
            TestDataInitializer.TruncateRelatedOptionBPlusTables();
            TestDataInitializer.TryToRegisterUser(phoneNumber, facilityCode);

            int month = 3;
            int year = 2014;
            string classicalReportKeyword = "PMTJ20";
            string message = string.Format("MAT.{0},{1},{2},J20,K2,105,2,0,0,107,107,0,J20,K8,107,0,0,0,0,0,0,0,0,0,0,0,0,0", 
                facilityCode, month, year);
            SMSReportingFormat format = SMSReportingFormat.RESTRICTIVE;
            ReportingMode mode = ReportingMode.DEFAULT;
            DataInputingMethod inputMethod = DataInputingMethod.SMS;
            ReportProcessor target = new ReportProcessor(phoneNumber, message, mode, format, inputMethod);

            bool bExpected = true;
            bool bActual = target.Submit();
            Assert.AreEqual(bExpected, bActual, target.ErrorText);

            using (var db = new IQSMS_TestDBContext())
            {
                var receivedSMS = (from r in db.ReceivedSMS.Include("ReportDatas")
                                   where r.FacCode == facilityCode &&
                                   r.Period == month && r.Year == year &&
                                   r.Report.RepVersion == classicalReportKeyword
                                   select r).FirstOrDefault();

                Assert.IsNotNull(receivedSMS, "Report was not saved at all");
                Assert.IsNotNull(receivedSMS.ReportDatas, "Report data was not saved in classical report templates");

                var data = receivedSMS.ReportDatas;
                Assert.AreEqual(17, data.Count, "Saved report indicators does not match that of the report");

                Assert.AreEqual(facilityCode, data[0].Data, "Facility code is not saved well");
                Assert.AreEqual(month, int.Parse(data[1].Data), "Report month is not saved well");
                Assert.AreEqual(year, int.Parse(data[2].Data), "Report year is not saved well");
                Assert.AreEqual(107, int.Parse(data[3].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(0, int.Parse(data[4].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(0, int.Parse(data[5].Data), "Indicator 3 is not saved well");
                Assert.AreEqual(0, int.Parse(data[6].Data), "Indicator 4 is not saved well");
                Assert.AreEqual(0, int.Parse(data[7].Data), "Indicator 5 is not saved well");
                Assert.AreEqual(0, int.Parse(data[8].Data), "Indicator 6 is not saved well");
                Assert.AreEqual(0, int.Parse(data[9].Data), "Indicator 7 is not saved well");
                Assert.AreEqual(0, int.Parse(data[10].Data), "Indicator 1 is not saved well");
                Assert.AreEqual(0, int.Parse(data[11].Data), "Indicator 2 is not saved well");
                Assert.AreEqual(0, int.Parse(data[12].Data), "Indicator 3 is not saved well");
                Assert.AreEqual(0, int.Parse(data[13].Data), "Indicator 4 is not saved well");
                Assert.AreEqual(0, int.Parse(data[14].Data), "Indicator 5 is not saved well");
                Assert.AreEqual(0, int.Parse(data[15].Data), "Indicator 6 is not saved well");
                Assert.AreEqual(0, int.Parse(data[16].Data), "Indicator 7 is not saved well");
            }
        }
    }
}
